package com.ete.service.net.http

import com.ete.service.callback.platform.IUpdateBaseUrlListener
import com.ete.service.manager.ManagerConstant
import com.ete.service.net.http.ssl.SSLSocketClient
import com.ete.service.net.logging.Level
import com.ete.service.net.logging.LoggingInterceptor
import com.ete.service.net.progress.IProgressListener
import com.ete.service.net.progress.ProgressInterceptor
import com.ete.service.upload.net.logging.RequestHeaderInterceptor
import com.ete.service.util.log.EteLog
import com.ete.service.util.unique.UniqueUtils
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import okhttp3.internal.platform.Platform
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

/**
 * Author:LiXian
 * <p>
 * Desc:网络请求创建
 * Version:1.0
 * date 2023/2/16 9:35
 */
object RetrofitClient {

    const val TAG = "ServiceManagerRetrofitClient"

    private var baseUrl = ManagerConstant.RELEASE_BASE_URL
    private var mBuilder: Retrofit.Builder? = null

    private val mInterceptorsMap = HashMap<String, ProgressInterceptor>()

    private val mLoggingInterceptor: LoggingInterceptor = LoggingInterceptor.Builder() //构建者模式
        .loggable(true) //是否开启日志打印
        .setLevel(Level.BODY) //打印的等级
        .log(Platform.INFO) // 打印类型
        .request("Request") // request的Tag
        .response("Response") // Response的Tag
        .build()

    private val mOkHttpClient = OkHttpClient.Builder()
        .addInterceptor(mLoggingInterceptor)
        .connectTimeout(ManagerConstant.TIME_THIRTY_SECOND, TimeUnit.SECONDS)
        .readTimeout(ManagerConstant.TIME_THIRTY_SECOND, TimeUnit.SECONDS)
        .writeTimeout(ManagerConstant.TIME_THIRTY_SECOND, TimeUnit.SECONDS)
        .retryOnConnectionFailure(false) // 需要设置为false, 否则超时时间回变成设置的2倍
        .connectionPool(ConnectionPool())
        .addInterceptor(RequestHeaderInterceptor())
        .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
        .hostnameVerifier(SSLSocketClient.getHostnameVerifier())

    private val mOkHttp2Client = OkHttpClient.Builder()
        .addInterceptor(mLoggingInterceptor)
        .connectTimeout(ManagerConstant.TIME_THIRTY_SECOND, TimeUnit.SECONDS)
        .readTimeout(ManagerConstant.TIME_FIVE_MINUTE, TimeUnit.SECONDS)
        .writeTimeout(ManagerConstant.TIME_FIVE_MINUTE, TimeUnit.SECONDS)
        .retryOnConnectionFailure(false) // 需要设置为false, 否则超时时间回变成设置的2倍
        .connectionPool(ConnectionPool())
        .addInterceptor(RequestHeaderInterceptor())
        .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
        .hostnameVerifier(SSLSocketClient.getHostnameVerifier())

    private fun getRetrofitBuilder(): Retrofit.Builder {
        if (mBuilder == null) {
            synchronized(RetrofitClient::class.java) {
                if (mBuilder == null) {
                    mBuilder = Retrofit.Builder()
                        .baseUrl(baseUrl)
                        .addConverterFactory(GsonConverterFactory.create())
                }
            }
        }
        return mBuilder!!
    }

    fun <T> createProgressService(clazz: Class<T>, mListener: IProgressListener): T {
        val mInterceptor = ProgressInterceptor(mListener)
        val mProgressKey = UniqueUtils.getUniqueFlag()
        mInterceptorsMap[mProgressKey] = mInterceptor
        mOkHttp2Client.addInterceptor(mInterceptor)
        mListener.onStart(mProgressKey)
        return getRetrofitBuilder().client(mOkHttp2Client.build()).build().create(clazz)
    }

    /**
     * 移除进度拦截器
     */
    @JvmStatic
    fun removeProgressInterceptor(mProgressKey: String?) {
        if (mProgressKey != null) {
            val mInterceptor = mInterceptorsMap.remove(mProgressKey)
            if (mInterceptor != null) {
                val isRemove = mOkHttp2Client.interceptors().remove(mInterceptor)
                EteLog.d(TAG, "移除进度拦截器isRemove:[$isRemove]")
            }
        }
    }

    fun <T> createService(clazz: Class<T>): T {
        return getRetrofitBuilder().client(mOkHttpClient.build()).build().create(clazz)
    }

    /**
     * 更新平台地址
     *
     * @param httpUrl 平台地址
     */
    @Throws(Exception::class)
    fun updateBaseUrl(httpUrl: String, mListener: IUpdateBaseUrlListener?) {
        if (httpUrl.length < 10) {
            mListener?.onResult(false, "非法平台地址")
            return
        }
        try {
            baseUrl = httpUrl.takeIf { !it.endsWith(ManagerConstant.SYMBOL_SLASH) }
                ?.plus(ManagerConstant.SYMBOL_SLASH) ?: httpUrl
            mBuilder?.let {
                mBuilder = it.build().newBuilder().baseUrl(baseUrl)
            }
            mListener?.onResult(true)
        } catch (ex: java.lang.Exception) {
            EteLog.d(TAG, "更新平台地址错误ex:[${ex.message}]")
            mListener?.onResult(false, ex.message ?: "")
        }
    }
}